package com.teacher.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.teacher.common.CommonResult;
import com.teacher.common.JwtTokenUtil;
import com.teacher.pojo.dto.login.LoginDto;
import com.teacher.pojo.dto.student.StudentAddDto;
import com.teacher.pojo.dto.student.StudentGetDto;
import com.teacher.pojo.entity.*;
import com.teacher.mapper.PerStudentMapper;
import com.teacher.pojo.enums.PermissionType;
import com.teacher.pojo.json.PermissionList;
import com.teacher.pojo.json.RoleList;
import com.teacher.pojo.vo.student.StudentGetVo;
import com.teacher.security.entity.permission.Permission;
import com.teacher.security.entity.security.RedisUserInfo;
import com.teacher.security.service.IRedisService;
import com.teacher.service.IPerStudentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.teacher.service.IPerTeacherService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zfm
 * @since 2021-06-15
 */
@Service
public class PerStudentServiceImpl extends ServiceImpl<PerStudentMapper, PerStudent> implements IPerStudentService {

    @Autowired
    private PerStudentMapper perStudentMapper;

    @Autowired
    private IRedisService iRedisService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.expiration}")
    private Long expiration;

    @Value("${role.classMonitor}")
    private String classMonitor;

    @Value("${role.officeMonitor}")
    private String officeMonitor;

    @Value("${role.office}")
    private String office;

    @Value("${role.subjectMonitor}")
    private String subjectMonitor;

    @Value("${role.admin}")
    private String admin;

    @Autowired
    private IPerStudentService iPerStudentService;

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private IPerTeacherService iPerTeacherService;

    /**
     * 添加入党积极分子
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult<String> add(StudentAddDto dto) {
        // 校验是否存在
        if (this.getOne(new QueryWrapper<PerStudent>().lambda()
                .eq(PerStudent::getStudentKey, dto.getStudentKey()).last("limit 1")) != null) {
            return CommonResult.failed("该学生已存在");
        }
        PerStudent perStudent = new PerStudent();
        BeanUtils.copyProperties(dto, perStudent);
        if (this.save(perStudent)) {
            return CommonResult.success("添加成功");
        }
        return CommonResult.failed("添加失败");
    }

    /**
     * 查询学生信息
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult<IPage<StudentGetVo>> getPage(StudentGetDto dto) {
        Page<StudentGetVo> page = new Page<>(dto.getCurrentPage(), dto.getPageSize());
        IPage<StudentGetVo> iPage = perStudentMapper.getPage(page, dto);
        return CommonResult.success(iPage);
    }

    /**
     * 查询学号是否存在
     *
     * @param studentKey
     * @return
     */
    @Override
    public boolean isExit(String studentKey) {
        return this.getOne(new QueryWrapper<PerStudent>().lambda().eq(PerStudent::getStudentKey, studentKey).last("limit 1")) != null;
    }

    /**
     * 登录
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult<ConcurrentMap<String, Object>> login(LoginDto dto) {


        PerStudent perStudent = baseMapper.selectOne(new QueryWrapper<PerStudent>().lambda()
                .eq(PerStudent::getStudentKey, dto.getStaffNumber()));

        if (perStudent == null) {
            return CommonResult.failed("非法用户");
        }


        List<Permission> permissionList = new ArrayList<>();

        List<String> permissionValue = new ArrayList<>();

        RedisUserInfo redisUserInfo = new RedisUserInfo();

        String token = jwtTokenUtil.generateToken(perStudent.getStudentKey());

        redisUserInfo.setToken(token);

        redisUserInfo.setPermissionValue(permissionValue);

        redisUserInfo.setAllMenu(permissionList);

        iRedisService.set(perStudent.getStudentKey(), JSONUtil.toJsonStr(redisUserInfo));
        iRedisService.expire(perStudent.getStudentKey(), expiration);
        ConcurrentMap<String, Object> concurrentMap = new ConcurrentHashMap<>();
        concurrentMap.put("token", token);
        concurrentMap.put("permissionValueList", permissionValue);
        return CommonResult.success(concurrentMap);
    }

    /**
     * 远程搜索学生-带权限
     *
     * @param name
     * @return
     */
    @Override
    public CommonResult<List<PerStudent>> getByName(String name) {
        List<PerStudent> perStudentList = new ArrayList<>();
        PerStudent perStudent = iPerStudentService.getOne(new QueryWrapper<PerStudent>().lambda()
                .eq(PerStudent::getStudentKey, jwtTokenUtil.getUsernameByRequest(httpServletRequest)).last("limit 1"));

        // 学生返回自己
        if (perStudent != null) {
            PerStudent mine = new PerStudent();
            mine.setName(mine.getName() + "-" + mine.getStudentKey());
            perStudentList.add(mine);
            return CommonResult.success(perStudentList);
        }

        // 不是学生不是老师
        PerTeacher perTeacher = iPerTeacherService.getOne(new QueryWrapper<PerTeacher>().lambda()
                .eq(PerTeacher::getTeacherKey, jwtTokenUtil.getUsernameByRequest(httpServletRequest)).last("limit 1"));
        if (perTeacher == null) {
            return CommonResult.success(perStudentList);
        }


        // 是否超级管理员 学工办 学工部主任 查询所有学生
        if (perTeacher.getRoleInfo().contains(admin)
                || perTeacher.getRoleInfo().contains(office)
                || perTeacher.getRoleInfo().contains(officeMonitor)) {
            perStudentList = baseMapper.getListAll(name);
            for (PerStudent student : perStudentList) {
                student.setName(student.getName() + "-" + student.getStudentKey());
            }
            return CommonResult.success(perStudentList);
        }

        // 如果是班主任，就只查询自己班级信息
        // 是否班主任
        if (perTeacher.getRoleInfo().contains(classMonitor)) {
            String teacherKey = jwtTokenUtil.getUsernameByRequest(httpServletRequest);
            perStudentList = baseMapper.getListByTeacherKey(name, teacherKey);
            for (PerStudent student : perStudentList) {
                student.setName(student.getName() + "-" + student.getStudentKey());
            }
            return CommonResult.success(perStudentList);
        }

        return CommonResult.success(new ArrayList<>());
    }
}
